 // vue2对象响应式原理： Object.definedProperty()   对属性进行拦截
 // vue2数组响应式原理：
// 从数组圆形中获取这7个方法 并覆盖为可以发送更新通知的函数实现
const methods =['push','pop','shift','unshift','splice','reverse','sort']
const originalProto = Array.prototype
const arrayProto   =  Object.create(originalProto)
methods.forEach(method => {
    arrayProto[method] = function(){
        originalProto[method].apply(this,arguments)
        // 通知更新
        notifyUpdate()
    }

});


// observe思想 递归遍历传入的obj  定义每个属性的拦截
// observe  
 function observe(obj){
     if(typeof obj !=='object'||obj===null){
         return obj
     }
     if(Array.isArray(obj)){
         Object.setPrototypeOf(obj,arrayProto)
     }else{

         const keys = Object.keys(obj)
         for (let index = 0; index < keys.length; index++) {
             const key = keys[index];
             // 取出每个key 对obj每个key执行拦截
             defineReactive(obj,key,obj[key])
            }
        }
 }
 // 具体的定义指定的key拦截器
 function defineReactive(obj,key,val){
     observe(val)
     Object.defineProperty(obj,key,{
         get(){
             return val
         },
         set(newVal){
             if(newVal!==val){
                 // nweVal可能是对象
                 observe(newVal)
                notifyUpdate()
                 val = newVal
             }
         }
     })
 }

 function notifyUpdate(){
     console.log("页面更新")
 }

 const data = {foo:'foo',b:{a:1},list:[1,2,3]}

 observe(data)
// 普通更新
//  data.foo="foooooooo"
// 嵌套更新
// data.b.a=10
// 对象更新
// data.b={a:100}
// data.list.push(4)
// console.log(data)
 


//  问题分析
// 1. 需要响应化的数据较大时，递归遍历性能不好 消耗较大   
// 2. 新增或删除属性无法监听
// 3. 数组相应化需要额外实现
// 4. 修改语法有限制